//=======================================================
// ADV7611 MODEL  
//=======================================================

module adv7611_model(
	// RGB CLOCK //
	 input 		          		pclk
	// RGB CONTROL //
    ,output reg                 de
    ,output reg                 hs
    ,output reg                 vs
	// RGB DATA //
    ,output reg [8 -1: 0]       pr
    ,output reg [8 -1: 0]       pg
    ,output reg [8 -1: 0]       pb
	// Internal CONTROL & RESET_n//
    ,input                      reset_n
    ,input                      enable
);

//=======================================================
//  REG/WIRE declarations
//=======================================================
parameter VS = 3;

//! parameter DE = 32;
//! parameter HS = 16;
//! localparam HS_PRELOGE = 22;
//! localparam HS_PULSE = 12;
//! localparam HS_EPILOGE = 38;
//! localparam HS_ACTIVE = DE;
//! localparam HS_TOTAL = HS_PRELOGE + HS_PULSE + HS_EPILOGE + HS_ACTIVE;
//! 
//! localparam VS_PRELOGE = 4;
//! localparam VS_PULSE = 5;
//! localparam VS_EPILOGE = 9;
//! localparam VS_ACTIVE = HS;
//! localparam VS_TOTAL = VS_PRELOGE + VS_PULSE + VS_EPILOGE + VS_ACTIVE;

localparam HS_PRELOGE = 88;
localparam HS_PULSE = 44;
localparam HS_EPILOGE = 148;
localparam HS_ACTIVE = 1920;
localparam HS_TOTAL = 2200;

localparam VS_PRELOGE = 4;
localparam VS_PULSE = 5;
localparam VS_EPILOGE = 36;
localparam VS_ACTIVE = 6;
localparam VS_TOTAL = VS_PRELOGE + VS_PULSE + VS_EPILOGE + VS_ACTIVE;
//localparam VS_ACTIVE = 1080;
//localparam VS_TOTAL = 1125;

//=======================================================
//  REG/WIRE declarations
//=======================================================
reg                         enable_r1;
reg                         enable_r2;
reg                         start;

reg         [32 -1: 0]      frame;
reg         [32 -1: 0]      pixel;
reg         [32 -1: 0]      line;

//=======================================================
//  Structural coding
//=======================================================
//-- enable from cross clk domain. generate a start level from the enable posedge.
//-- start pix counter.
always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    enable_r1 <= 0;
    enable_r2 <= 0;
  end else begin
    enable_r1 <= enable;
    enable_r2 <= enable_r1;
  end
end

always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    start <= 0;
  end else if (frame == VS) begin
    start <= 0;
  end else if((enable_r1 == 1'b1) && (enable_r2 == 1'b0)) begin  //posedge
    start <= 1;
  end
end

always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    pixel <= 0;
  end else if (pixel == HS_TOTAL-1) begin
    pixel <= 0;
  end else if (start) begin
    pixel <= pixel + 1'b1;
  end
end
assign pixel_pulse = (pixel == HS_TOTAL -1);

always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    line <= 0;
  end else if ((line == VS_TOTAL-1) && (pixel == HS_TOTAL -1))begin
    line <= 0;
  end else if (pixel == HS_TOTAL-1) begin
    line <= line + 1;
  end
end
assign line_pulse = (line == VS_TOTAL -1);

always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    frame <= 0;
  end else if ((line == VS_TOTAL-1) && (pixel == HS_TOTAL -1))begin
    frame <= frame + 1;
  end
end

//-- vs output low
always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    vs <= 1;
  end else if ((line < VS_PRELOGE -1)
              && (pixel == HS_TOTAL -1)) begin
    vs <= 1;
  end else if (((line >= VS_PRELOGE -1) && (line < (VS_PRELOGE + VS_PULSE -1))) 
              && (pixel == HS_TOTAL -1)) begin
    vs <= 0;
  end else if (((line >= VS_PRELOGE + VS_PULSE -1) && (line < (VS_TOTAL -1))) 
              && (pixel == HS_TOTAL -1)) begin
    vs <= 1;
  end
end

//-- hs output low
always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    hs <= 1;
  end else if ((pixel < HS_PRELOGE-1) || (pixel >= (HS_TOTAL -1)))begin
    hs <= 1;
  end else if ((pixel >= HS_PRELOGE-1) && (pixel < (HS_PRELOGE + HS_PULSE -1))) begin
    hs <= 0;
  end else if ((pixel >= (HS_PRELOGE + HS_PULSE -1)) && (pixel < (HS_TOTAL -1))) begin
    hs <= 1;
  end
end

//-- de output high
always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    de <= 0;
  end else if ((pixel < (HS_PRELOGE + HS_PULSE + HS_EPILOGE -1)) || (pixel >= (HS_TOTAL -1))) begin
    de <= 0;
  end else if (((line >= VS_PRELOGE + VS_PULSE + VS_EPILOGE -1) && (line < (VS_TOTAL -1))) 
            && ((pixel >= (HS_PRELOGE + HS_PULSE + HS_EPILOGE -1)) && (pixel < (HS_TOTAL -1))))begin
//  end else if ((pixel >= (HS_PRELOGE + HS_PULSE + HS_EPILOGE -1)) && (pixel < (HS_TOTAL -1)))begin
    de <= 1;
  end
end

//-- rgb data output
always@(posedge pclk or negedge reset_n)
begin
  if(!reset_n) begin
    pr <= 8'h0;
    pg <= 8'h40;
    pb <= 8'h80;
  end else if ((pixel < (HS_PRELOGE + HS_PULSE + HS_EPILOGE -1)) || (pixel >= (HS_TOTAL -1))) begin
    pr <= 8'h0  + line + frame;
    pg <= 8'h40 + line + frame;
    pb <= 8'h80 + line + frame;
  end else if (((line >= VS_PRELOGE + VS_PULSE + VS_EPILOGE -1) && (line < (VS_TOTAL -1))) 
            && ((pixel >= (HS_PRELOGE + HS_PULSE + HS_EPILOGE -1)) && (pixel < (HS_TOTAL -1))))begin
    pr <= pr + 1'b1;
    pg <= pg + 1'b1;
    pb <= pb + 1'b1;
  end
end

endmodule
